﻿// 公司名称：松山湖材料实验室
// 项目名称：Micromach.LaserController.Micromach.Common
// 文件名称：ConvertHelper.cs
// 创建日期：2019/03/15 16:41
// 功能描述：
// 作  者： 陈琦
// 最后修改：

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RoboSensors.Tools
{
    public static class ConvertHelper
    {
        /// <summary>
        /// 二进制数组转换为单字节 字符串
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        public static string ToHexString(this byte[] cmd)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in cmd)
            {
                sb.Append(b.ToString("x2"));
                sb.Append(" ");
            }
            return sb.ToString();
        }

        public static string Double2String(this double d, int roundNumber = 6)
        {
            return Math.Round(d, roundNumber).ToString("F" + roundNumber);
        }
        /// <summary>
        /// 异或校验函数
        /// </summary>
        /// <param name="arry">要校验的数组</param>
        /// <param name="offset">开始位置</param>
        /// <param name="length">要校验的长度</param>
        /// <returns></returns>
        public static byte XorCheck(this byte[] arry, int offset, int length)
        {

            byte result = arry[offset];
            for (int i = offset + 1; i < length + offset; i++)
            {
                result ^= arry[i];
            }
            return result;

        }
        public static byte[] ToBytes(this float val)
        {
            return BitConverter.GetBytes(val).Reverse().ToArray();
        }
        public static bool ToBool(this float val)
        {
            return Convert.ToBoolean(val);
        }
        /// <summary>
        /// 计算速度10进制速度转换为2字节byte数组
        /// </summary>
        /// <param name="iValue">10进制速度值</param>
        /// <returns></returns>
        public static byte[] ToBytes(this short iValue)
        {
            var hValue = (iValue >> 8) & 0xFF;
            var lValue = iValue & 0xFF;
            return new[] { (byte)hValue, (byte)lValue };
        }
        /// <summary>
        /// 计算速度10进制速度转换为2字节byte数组
        /// </summary>
        /// <param name="iValue">10进制速度值</param>
        /// <returns></returns>
        public static byte[] ToBytes(this int iValue)
        {
            return ((short)iValue).ToBytes();
        }
        public static ushort ToShort(this byte[] bt)
        {
            if (bt.Length != 2)
            {
                throw new Exception("入参传递错误！，请重新传");
            }
            return BitConverter.ToUInt16(bt.Reverse().ToArray(), 0);
            //short s0 = (short)(bt[0] & 0xFF);
            //short s1 = (short)(bt[1] & 0xFF);
            //return (short)(s1 | s0);
        }
        public static float ToFloat(this IEnumerable<byte> vals, int index)
        {
            var val = vals.ToArray();
            if (val == null)
            {
                throw new Exception("传入的字节数组不能为空！");
            }
            const int count = 4;
            if (val.Length - index < count)
            {
                throw new Exception(string.Format("{0}的位置向后没有4个字节，不能组成float，请检查！", index));
            }

            var temp = new byte[count];
            Array.Copy(val, index, temp, 0, count);
            return BitConverter.ToSingle(temp.Reverse().ToArray(), 0);
        }
        public static float ToFloat(this string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                throw new Exception("传入参数不能为空!");
            }
            float result;
            if (float.TryParse(str, out result))
            {
                return result;
            }
            return -1f;
        }

        public static string ConvertBase(string value, int from, int to)
        {
            if (!smethod_0(from))
            {
                throw new ArgumentException("参数from只能是2,8,10,16四个值。");
            }
            if (!smethod_0(to))
            {
                throw new ArgumentException("参数to只能是2,8,10,16四个值。");
            }
            int value2 = Convert.ToInt32(value, from);
            string text = Convert.ToString(value2, to);
            if (to == 2)
            {
                switch (text.Length)
                {
                    case 3:
                        text = "00000" + text;
                        break;
                    case 4:
                        text = "0000" + text;
                        break;
                    case 5:
                        text = "000" + text;
                        break;
                    case 6:
                        text = "00" + text;
                        break;
                    case 7:
                        text = "0" + text;
                        break;
                }
            }
            return text;
        }

        private static bool smethod_0(int int_0)
        {
            if (int_0 != 2 && int_0 != 8 && int_0 != 10 && int_0 != 16)
            {
                return false;
            }
            return true;
        }

        public static byte[] StringToBytes(string text)
        {
            return Encoding.Default.GetBytes(text);
        }

        public static byte[] StringToBytes(string text, Encoding encoding)
        {
            return encoding.GetBytes(text);
        }

        public static string BytesToString(byte[] bytes)
        {
            return Encoding.Default.GetString(bytes);
        }

        public static string BytesToString(byte[] bytes, Encoding encoding)
        {
            return encoding.GetString(bytes);
        }

        public static int BytesToInt32(byte[] data)
        {
            if (data.Length >= 4)
            {
                int result = 0;
                if (data.Length >= 4)
                {
                    byte[] array = new byte[4];
                    Buffer.BlockCopy(data, 0, array, 0, 4);
                    result = BitConverter.ToInt32(array, 0);
                }
                return result;
            }
            return 0;
        }

        public static int ToInt32<T>(T data, int defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToInt32(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static int ToInt32(string data, int defValue)
        {
            if (!string.IsNullOrEmpty(data))
            {
                int result;
                if (!int.TryParse(data, out result))
                {
                    return defValue;
                }
                return result;
            }
            return defValue;
        }

        public static int ToInt32(object data, int defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToInt32(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static bool ToBoolean<T>(T data, bool defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToBoolean(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static bool ToBoolean(string data, bool defValue)
        {
            if (!string.IsNullOrEmpty(data))
            {
                bool result;
                if (!bool.TryParse(data, out result))
                {
                    return defValue;
                }
                return result;
            }
            return defValue;
        }

        public static bool ToBoolean(object data, bool defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToBoolean(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static float ToFloat<T>(T data, float defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToSingle(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static float ToFloat(object data, float defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToSingle(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static float ToFloat(string data, float defValue)
        {
            if (!string.IsNullOrEmpty(data))
            {
                float result;
                if (!float.TryParse(data, out result))
                {
                    return defValue;
                }
                return result;
            }
            return defValue;
        }

        public static double ToDouble<T>(T data, double defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToDouble(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static double ToDouble<T>(T data, int decimals, double defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Math.Round(Convert.ToDouble(data), decimals);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static double ToDouble(object data, double defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToDouble(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static double ToDouble(this string data, double defValue)
        {
            if (!string.IsNullOrEmpty(data))
            {
                double result;
                if (!double.TryParse(data, out result))
                {
                    return defValue;
                }
                return result;
            }
            return defValue;
        }

        public static double ToDouble(object data, int decimals, double defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Math.Round(Convert.ToDouble(data), decimals);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static double ToDouble(string data, int decimals, double defValue)
        {
            if (!string.IsNullOrEmpty(data))
            {
                double result;
                if (!double.TryParse(data, out result))
                {
                    return defValue;
                }
                return Math.Round(result, decimals);
            }
            return defValue;
        }

        public static object ConvertTo(object data, Type targetType)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                Type type = data.GetType();
                if (!(targetType == type))
                {
                    if ((!(targetType == typeof(Guid)) && !(targetType == typeof(Guid?))) || !(type == typeof(string)))
                    {
                        if (targetType.IsEnum)
                        {
                            try
                            {
                                return Enum.Parse(targetType, data.ToString(), true);
                            }
                            catch
                            {
                                return Enum.ToObject(targetType, data);
                            }
                        }
                        if (targetType.IsGenericType)
                        {
                            targetType = targetType.GetGenericArguments()[0];
                        }
                        return Convert.ChangeType(data, targetType);
                    }
                    if (!string.IsNullOrEmpty(data.ToString()))
                    {
                        return new Guid(data.ToString());
                    }
                    return null;
                }
                return data;
            }
            return null;
        }

        public static T ConvertTo<T>(object data)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                object obj = ConvertTo(data, typeof(T));
                if (obj != null)
                {
                    return (T)obj;
                }
                return default(T);
            }
            return default(T);
        }

        public static decimal ToDecimal<T>(T data, decimal defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToDecimal(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static decimal ToDecimal(object data, decimal defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToDecimal(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static decimal ToDecimal(string data, decimal defValue)
        {
            if (!string.IsNullOrEmpty(data))
            {
                decimal result;
                if (!decimal.TryParse(data, out result))
                {
                    return defValue;
                }
                return result;
            }
            return defValue;
        }

        public static DateTime ToDateTime<T>(T data, DateTime defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToDateTime(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static DateTime ToDateTime(object data, DateTime defValue)
        {
            if (data != null && !Convert.IsDBNull(data))
            {
                try
                {
                    return Convert.ToDateTime(data);
                }
                catch
                {
                    return defValue;
                }
            }
            return defValue;
        }

        public static DateTime ToDateTime(string data, DateTime defValue)
        {
            if (!string.IsNullOrEmpty(data))
            {
                DateTime result;
                if (!DateTime.TryParse(data, out result))
                {
                    return defValue;
                }
                return result;
            }
            return defValue;
        }

        public static string ConvertToSBC(string input)
        {
            if (!string.IsNullOrWhiteSpace(input))
            {
                char[] array = input.ToCharArray();
                for (int i = 0; i < array.Length; i++)
                {
                    if (array[i] == ' ')
                    {
                        array[i] = '\u3000';
                    }
                    else if (array[i] < '\u007f')
                    {
                        array[i] = (char)(array[i] + 65248);
                    }
                }
                return new string(array);
            }
            return "";
        }

        public static string ConvertToDBC(string input)
        {
            if (!string.IsNullOrWhiteSpace(input))
            {
                char[] array = input.ToCharArray();
                for (int i = 0; i < array.Length; i++)
                {
                    if (array[i] == '\u3000')
                    {
                        array[i] = ' ';
                    }
                    else if (array[i] > '\uff00' && array[i] < '｟')
                    {
                        array[i] = (char)(array[i] - 65248);
                    }
                }
                return new string(array);
            }
            return "";
        }

        public static double ToRound(this double val, int round = 3)
        {
            return Math.Round(val, round);
        }
        public static float ToRound(this float val, int round = 3)
        {
            return (float)Math.Round(val, round);
        }

        public static short ToShort(this int iValue)
        {
            return Convert.ToInt16(iValue);
        }
    }
}